home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / BEZIER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-18  |  46.9 KB  |  2,353 lines

  1. /****************************************************************************
  2. *                   bezier.c
  3. *
  4. *  This module implements the code for Bezier bicubic patch shapes
  5. *
  6. *  This file was written by Alexander Enzmann.  He wrote the code for
  7. *  bezier bicubic patches and generously provided us these enhancements.
  8. *
  9. *  from Persistence of Vision(tm) Ray Tracer
  10. *  Copyright 1996 Persistence of Vision Team
  11. *---------------------------------------------------------------------------
  12. *  NOTICE: This source code file is provided so that users may experiment
  13. *  with enhancements to POV-Ray and to port the software to platforms other
  14. *  than those supported by the POV-Ray Team.  There are strict rules under
  15. *  which you are permitted to use this file.  The rules are in the file
  16. *  named POVLEGAL.DOC which should be distributed with this file. If
  17. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  18. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  19. *  Forum.  The latest version of POV-Ray may be found there as well.
  20. *
  21. * This program is based on the popular DKB raytracer version 2.12.
  22. * DKBTrace was originally written by David K. Buck.
  23. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  24. *
  25. *****************************************************************************/
  26.  
  27. #include "frame.h"
  28. #include "vector.h"
  29. #include "povproto.h"
  30. #include "bezier.h"
  31. #include "matrices.h"
  32. #include "objects.h"
  33. #include "povray.h"
  34.  
  35.  
  36.  
  37. /*****************************************************************************
  38. * Local preprocessor defines
  39. ******************************************************************************/
  40.  
  41. #define BEZIER_EPSILON 1.0e-10
  42.  
  43. #define BEZIER_TOLERANCE 1.0e-5
  44.  
  45.  
  46.  
  47. /*****************************************************************************
  48. * Local typedefs
  49. ******************************************************************************/
  50.  
  51.  
  52.  
  53. /*****************************************************************************
  54. * Static functions
  55. ******************************************************************************/
  56.  
  57. static int InvertMatrix PARAMS((VECTOR in[3], VECTOR out[3]));
  58. static void bezier_value PARAMS((VECTOR(*Control_Points)[4][4], DBL u0, DBL v0, VECTOR P, VECTOR N));
  59. static int intersect_subpatch PARAMS((BICUBIC_PATCH *, RAY *, VECTOR [3], DBL [3], DBL [3], DBL *, VECTOR , VECTOR , DBL *, DBL *));
  60. static void find_average PARAMS((int, VECTOR *, VECTOR , DBL *));
  61. static int spherical_bounds_check PARAMS((RAY *, VECTOR , DBL));
  62. static int intersect_bicubic_patch0 PARAMS((RAY *, BICUBIC_PATCH *, ISTACK *));
  63. static DBL point_plane_distance PARAMS((VECTOR , VECTOR , DBL *));
  64. static DBL determine_subpatch_flatness PARAMS((VECTOR(*)[4][4]));
  65. static int flat_enough PARAMS((BICUBIC_PATCH *, VECTOR(*)[4][4]));
  66. static void bezier_bounding_sphere PARAMS((VECTOR(*)[4][4], VECTOR , DBL *));
  67. static int bezier_subpatch_intersect PARAMS((RAY *, BICUBIC_PATCH *, VECTOR(*)[4][4], DBL, DBL, DBL, DBL, ISTACK *));
  68. static void bezier_split_left_right PARAMS((VECTOR(*)[4][4], VECTOR(*)[4][4], VECTOR(*)[4][4]));
  69. static void bezier_split_up_down PARAMS((VECTOR(*)[4][4], VECTOR(*)[4][4], VECTOR(*)[4][4]));
  70. static int bezier_subdivider PARAMS((RAY *, BICUBIC_PATCH *, VECTOR(*)[4][4], DBL, DBL, DBL, DBL, int, ISTACK *));
  71. static void bezier_tree_deleter PARAMS((BEZIER_NODE *Node));
  72. static BEZIER_NODE *bezier_tree_builder PARAMS((BICUBIC_PATCH *Object, VECTOR(*Patch)[4][4], DBL u0, DBL u1, DBL v0, DBL v1, int depth));
  73. static int bezier_tree_walker PARAMS((RAY *, BICUBIC_PATCH *, BEZIER_NODE *, ISTACK *));
  74. static BEZIER_NODE *create_new_bezier_node PARAMS((void));
  75. static BEZIER_VERTICES *create_bezier_vertex_block PARAMS((void));
  76. static BEZIER_CHILDREN *create_bezier_child_block PARAMS((void));
  77. static int subpatch_normal PARAMS((VECTOR v1, VECTOR v2, VECTOR v3, VECTOR Result, DBL *d));
  78. static int All_Bicubic_Patch_Intersections PARAMS((OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack));
  79. static int Inside_Bicubic_Patch PARAMS((VECTOR IPoint, OBJECT *Object));
  80. static void Bicubic_Patch_Normal PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
  81. static void *Copy_Bicubic_Patch PARAMS((OBJECT *Object));
  82. static void Translate_Bicubic_Patch PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  83. static void Rotate_Bicubic_Patch PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  84. static void Scale_Bicubic_Patch PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  85. static void Transform_Bicubic_Patch PARAMS((OBJECT *Object, TRANSFORM *Trans));
  86. static void Invert_Bicubic_Patch PARAMS((OBJECT *Object));
  87. static void Destroy_Bicubic_Patch PARAMS((OBJECT *Object));
  88.  
  89.  
  90.  
  91. /*****************************************************************************
  92. * Local variables
  93. ******************************************************************************/
  94.  
  95. static METHODS Bicubic_Patch_Methods =
  96. {
  97.   All_Bicubic_Patch_Intersections,
  98.   Inside_Bicubic_Patch, Bicubic_Patch_Normal, Copy_Bicubic_Patch,
  99.   Translate_Bicubic_Patch, Rotate_Bicubic_Patch,
  100.   Scale_Bicubic_Patch, Transform_Bicubic_Patch, Invert_Bicubic_Patch,
  101.   Destroy_Bicubic_Patch
  102. };
  103.  
  104. static int max_depth_reached;
  105.  
  106. static DBL C[4] = { 1.0, 3.0, 3.0, 1.0 };
  107.  
  108.  
  109.  
  110. /*****************************************************************************
  111. *
  112. * FUNCTION
  113. *
  114. *   create_new_bezier_node
  115. *
  116. * INPUT
  117. *   
  118. * OUTPUT
  119. *   
  120. * RETURNS
  121. *   
  122. * AUTHOR
  123. *
  124. *   Alexander Enzmann
  125. *   
  126. * DESCRIPTION
  127. *
  128. *   -
  129. *
  130. * CHANGES
  131. *
  132. *   -
  133. *
  134. ******************************************************************************/
  135.  
  136. static BEZIER_NODE *create_new_bezier_node()
  137. {
  138.   BEZIER_NODE *Node = (BEZIER_NODE *)POV_MALLOC(sizeof(BEZIER_NODE), "bezier node");
  139.   
  140.   Node->Data_Ptr = NULL;
  141.  
  142.   return (Node);
  143. }
  144.  
  145.  
  146.  
  147. /*****************************************************************************
  148. *
  149. * FUNCTION
  150. *
  151. *   create_bezier_vertex_block
  152. *
  153. * INPUT
  154. *   
  155. * OUTPUT
  156. *   
  157. * RETURNS
  158. *   
  159. * AUTHOR
  160. *
  161. *   Alexander Enzmann
  162. *   
  163. * DESCRIPTION
  164. *
  165. *   -
  166. *
  167. * CHANGES
  168. *
  169. *   -
  170. *
  171. ******************************************************************************/
  172.  
  173. static BEZIER_VERTICES *create_bezier_vertex_block()
  174. {
  175.   BEZIER_VERTICES *Vertices;
  176.  
  177.   Vertices = (BEZIER_VERTICES *)POV_MALLOC(sizeof(BEZIER_VERTICES), "bezier vertices");
  178.   
  179.   return (Vertices);
  180. }
  181.  
  182.  
  183.  
  184. /*****************************************************************************
  185. *
  186. * FUNCTION
  187. *
  188. *   create_bezier_child_block
  189. *
  190. * INPUT
  191. *   
  192. * OUTPUT
  193. *   
  194. * RETURNS
  195. *   
  196. * AUTHOR
  197. *
  198. *   Alexander Enzmann
  199. *   
  200. * DESCRIPTION
  201. *
  202. *   -
  203. *
  204. * CHANGES
  205. *
  206. *   -
  207. *
  208. ******************************************************************************/
  209.  
  210. static BEZIER_CHILDREN *create_bezier_child_block()
  211. {
  212.   BEZIER_CHILDREN *Children;
  213.   
  214.   Children = (BEZIER_CHILDREN *)POV_MALLOC(sizeof(BEZIER_CHILDREN), "bezier children");
  215.   
  216.   return (Children);
  217. }
  218.  
  219.  
  220.  
  221. /*****************************************************************************
  222. *
  223. * FUNCTION
  224. *
  225. *   bezier_tree_builder
  226. *
  227. * INPUT
  228. *   
  229. * OUTPUT
  230. *   
  231. * RETURNS
  232. *   
  233. * AUTHOR
  234. *
  235. *   Alexander Enzmann
  236. *   
  237. * DESCRIPTION
  238. *
  239. *   -
  240. *
  241. * CHANGES
  242. *
  243. *   -
  244. *
  245. ******************************************************************************/
  246.  
  247. static BEZIER_NODE *bezier_tree_builder(Object, Patch, u0, u1, v0, v1, depth)
  248. BICUBIC_PATCH *Object;
  249. VECTOR(*Patch)[4][4];
  250. DBL u0, u1, v0, v1;
  251. int depth;
  252. {
  253.   VECTOR Lower_Left[4][4], Lower_Right[4][4];
  254.   VECTOR Upper_Left[4][4], Upper_Right[4][4];
  255.   BEZIER_CHILDREN *Children;
  256.   BEZIER_VERTICES *Vertices;
  257.   BEZIER_NODE *Node = create_new_bezier_node();
  258.   
  259.   if (depth > max_depth_reached)
  260.   {
  261.     max_depth_reached = depth;
  262.   }
  263.   
  264.   /* Build the bounding sphere for this subpatch. */
  265.   
  266.   bezier_bounding_sphere(Patch, Node->Center, &(Node->Radius_Squared));
  267.   
  268.   /*
  269.    * If the patch is close to being flat, then just perform
  270.    * a ray-plane intersection test.
  271.    */
  272.   
  273.   if (flat_enough(Object, Patch))
  274.   {
  275.     /* The patch is now flat enough to simply store the corners. */
  276.     
  277.     Node->Node_Type = BEZIER_LEAF_NODE;
  278.     
  279.     Vertices = create_bezier_vertex_block();
  280.     
  281.     Assign_Vector(Vertices->Vertices[0], (*Patch)[0][0]);
  282.     Assign_Vector(Vertices->Vertices[1], (*Patch)[0][3]);
  283.     Assign_Vector(Vertices->Vertices[2], (*Patch)[3][3]);
  284.     Assign_Vector(Vertices->Vertices[3], (*Patch)[3][0]);
  285.     
  286.     Vertices->uvbnds[0] = u0;
  287.     Vertices->uvbnds[1] = u1;
  288.     Vertices->uvbnds[2] = v0;
  289.     Vertices->uvbnds[3] = v1;
  290.  
  291.     Node->Data_Ptr = (void *)Vertices;
  292.   }
  293.   else
  294.   {
  295.     if (depth >= Object->U_Steps)
  296.     {
  297.       if (depth >= Object->V_Steps)
  298.       {
  299.         /* We are at the max recursion depth. Just store corners. */
  300.         
  301.         Node->Node_Type = BEZIER_LEAF_NODE;
  302.         
  303.         Vertices = create_bezier_vertex_block();
  304.         
  305.         Assign_Vector(Vertices->Vertices[0], (*Patch)[0][0]);
  306.         Assign_Vector(Vertices->Vertices[1], (*Patch)[0][3]);
  307.         Assign_Vector(Vertices->Vertices[2], (*Patch)[3][3]);
  308.         Assign_Vector(Vertices->Vertices[3], (*Patch)[3][0]);
  309.         
  310.         Vertices->uvbnds[0] = u0;
  311.         Vertices->uvbnds[1] = u1;
  312.         Vertices->uvbnds[2] = v0;
  313.         Vertices->uvbnds[3] = v1;
  314.         
  315.         Node->Data_Ptr = (void *)Vertices;
  316.       }
  317.       else
  318.       {
  319.         bezier_split_up_down(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left);
  320.         
  321.         Node->Node_Type = BEZIER_INTERIOR_NODE;
  322.         
  323.         Children = create_bezier_child_block();
  324.         
  325.         Children->Children[0] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Left, u0, u1, v0, (v0 + v1) / 2.0, depth + 1);
  326.         Children->Children[1] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Upper_Left, u0, u1, (v0 + v1) / 2.0, v1, depth + 1);
  327.         
  328.         Node->Count = 2;
  329.         
  330.         Node->Data_Ptr = (void *)Children;
  331.       }
  332.     }
  333.     else
  334.     {
  335.       if (depth >= Object->V_Steps)
  336.       {
  337.         bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  338.         
  339.         Node->Node_Type = BEZIER_INTERIOR_NODE;
  340.         
  341.         Children = create_bezier_child_block();
  342.         
  343.         Children->Children[0] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Left, u0, (u0 + u1) / 2.0, v0, v1, depth + 1);
  344.         Children->Children[1] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Right, (u0 + u1) / 2.0, u1, v0, v1, depth + 1);
  345.         
  346.         Node->Count = 2;
  347.         
  348.         Node->Data_Ptr = (void *)Children;
  349.       }
  350.       else
  351.       {
  352.         bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  353.         
  354.         bezier_split_up_down((VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left);
  355.         
  356.         bezier_split_up_down((VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Upper_Right);
  357.         
  358.         Node->Node_Type = BEZIER_INTERIOR_NODE;
  359.         
  360.         Children = create_bezier_child_block();
  361.         
  362.         Children->Children[0] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Left, u0, (u0 + u1) / 2.0, v0, (v0 + v1) / 2.0, depth + 1);
  363.         Children->Children[1] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Upper_Left, u0, (u0 + u1) / 2.0, (v0 + v1) / 2.0, v1, depth + 1);
  364.         Children->Children[2] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Lower_Right, (u0 + u1) / 2.0, u1, v0, (v0 + v1) / 2.0, depth + 1);
  365.         Children->Children[3] = bezier_tree_builder(Object, (VECTOR(*)[4][4])Upper_Right, (u0 + u1) / 2.0, u1, (v0 + v1) / 2.0, v1, depth + 1);
  366.         
  367.         Node->Count = 4;
  368.         
  369.         Node->Data_Ptr = (void *)Children;
  370.       }
  371.     }
  372.   }
  373.   
  374.   return (Node);
  375. }
  376.  
  377.  
  378.  
  379. /*****************************************************************************
  380. *
  381. * FUNCTION
  382. *
  383. *   bezier_value
  384. *
  385. * INPUT
  386. *
  387. * OUTPUT
  388. *   
  389. * RETURNS
  390. *   
  391. * AUTHOR
  392. *
  393. *   Alexander Enzmann
  394. *   
  395. * DESCRIPTION
  396. *
  397. *   Determine the position and normal at a single coordinate
  398. *   point (u, v) on a Bezier patch.
  399. *
  400. * CHANGES
  401. *
  402. *   -
  403. *
  404. ******************************************************************************/
  405.  
  406. static void bezier_value(Control_Points, u0, v0, P, N)
  407. VECTOR(*Control_Points)[4][4];
  408. DBL u0, v0;
  409. VECTOR P, N;
  410. {
  411.   int i, j;
  412.   DBL c, t, ut, vt;
  413.   DBL u[4], uu[4], v[4], vv[4];
  414.   DBL du[4], duu[4], dv[4], dvv[4];
  415.   VECTOR U1, V1;
  416.   
  417.   /* Calculate binomial coefficients times coordinate positions. */
  418.   
  419.   u[0] = 1.0; uu[0] = 1.0; du[0] = 0.0; duu[0] = 0.0;
  420.   v[0] = 1.0; vv[0] = 1.0; dv[0] = 0.0; dvv[0] = 0.0;
  421.  
  422.   for (i = 1; i < 4; i++)
  423.   {
  424.     u[i] = u[i - 1] * u0;  uu[i] = uu[i - 1] * (1.0 - u0);
  425.     v[i] = v[i - 1] * v0;  vv[i] = vv[i - 1] * (1.0 - v0);
  426.  
  427.     du[i] = i * u[i - 1];  duu[i] = -i * uu[i - 1];
  428.     dv[i] = i * v[i - 1];  dvv[i] = -i * vv[i - 1];
  429.   }
  430.  
  431.   /* Now evaluate position and tangents based on control points. */
  432.  
  433.   Make_Vector(P, 0, 0, 0);
  434.   Make_Vector(U1, 0, 0, 0);
  435.   Make_Vector(V1, 0, 0, 0);
  436.  
  437.   for (i = 0; i < 4; i++)
  438.   {
  439.     for (j = 0; j < 4; j++)
  440.     {
  441.       c = C[i] * C[j];
  442.       
  443.       ut = u[i] * uu[3 - i];
  444.       vt = v[j] * vv[3 - j];
  445.       
  446.       t = c * ut * vt;
  447.       
  448.       VAddScaledEq(P, t, (*Control_Points)[i][j]);
  449.       
  450.       t = c * vt * (du[i] * uu[3 - i] + u[i] * duu[3 - i]);
  451.       
  452.       VAddScaledEq(U1, t, (*Control_Points)[i][j]);
  453.       
  454.       t = c * ut * (dv[j] * vv[3 - j] + v[j] * dvv[3 - j]);
  455.       
  456.       VAddScaledEq(V1, t, (*Control_Points)[i][j]);
  457.     }
  458.   }
  459.   
  460.   /* Make the normal from the cross product of the tangents. */
  461.   
  462.   VCross(N, U1, V1);
  463.   
  464.   VDot(t, N, N);
  465.   
  466.   if (t > BEZIER_EPSILON)
  467.   {
  468.     t = 1.0 / sqrt(t);
  469.     
  470.     VScaleEq(N, t);
  471.   }
  472.   else
  473.   {
  474.     Make_Vector(N, 1, 0, 0)
  475.   }
  476. }
  477.  
  478.  
  479.  
  480. /*****************************************************************************
  481. *
  482. * FUNCTION
  483. *
  484. *   subpatch_normal
  485. *
  486. * INPUT
  487. *   
  488. * OUTPUT
  489. *   
  490. * RETURNS
  491. *   
  492. * AUTHOR
  493. *
  494. *   Alexander Enzmann
  495. *   
  496. * DESCRIPTION
  497. *
  498. *   Calculate the normal to a subpatch (triangle) return the vector
  499. *   <1.0 0.0 0.0> if the triangle is degenerate.
  500. *
  501. * CHANGES
  502. *
  503. *   -
  504. *
  505. ******************************************************************************/
  506.  
  507. static int subpatch_normal(v1, v2, v3, Result, d)
  508. VECTOR v1, v2, v3, Result;
  509. DBL *d;
  510. {
  511.   VECTOR V1, V2;
  512.   DBL Length;
  513.   
  514.   VSub(V1, v1, v2);
  515.   VSub(V2, v3, v2);
  516.  
  517.   VCross(Result, V1, V2);
  518.  
  519.   VLength(Length, Result);
  520.  
  521.   if (Length < BEZIER_EPSILON)
  522.   {
  523.     Make_Vector(Result, 1.0, 0.0, 0.0);
  524.  
  525.     *d = -1.0 * v1[X];
  526.  
  527.     return (0);
  528.   }
  529.   else
  530.   {
  531.     VInverseScale(Result, Result, Length);
  532.  
  533.     VDot(*d, Result, v1);
  534.  
  535.     *d = 0.0 - *d;
  536.  
  537.     return (1);
  538.   }
  539. }
  540.  
  541.  
  542.  
  543. /*****************************************************************************
  544. *
  545. * FUNCTION
  546. *
  547. *   InvertMatrix
  548. *
  549. * INPUT
  550. *
  551. * OUTPUT
  552. *
  553. * RETURNS
  554. *
  555. * AUTHOR
  556. *
  557. *   Alexander Enzmann
  558. *
  559. * DESCRIPTION
  560. *
  561. *   -
  562. *
  563. * CHANGES
  564. *
  565. *   -
  566. *
  567. ******************************************************************************/
  568.  
  569. static int InvertMatrix(in, out)
  570. VECTOR in[3], out[3];
  571. {
  572.   int i;
  573.   DBL det;
  574.  
  575.   out[0][X] =   (in[1][Y] * in[2][Z] - in[1][Z] * in[2][Y]);
  576.   out[1][X] = - (in[0][Y] * in[2][Z] - in[0][Z] * in[2][Y]);
  577.   out[2][X] =   (in[0][Y] * in[1][Z] - in[0][Z] * in[1][Y]);
  578.  
  579.   out[0][Y] = - (in[1][X] * in[2][Z] - in[1][Z] * in[2][X]);
  580.   out[1][Y] =   (in[0][X] * in[2][Z] - in[0][Z] * in[2][X]);
  581.   out[2][Y] = - (in[0][X] * in[1][Z] - in[0][Z] * in[1][X]);
  582.  
  583.   out[0][Z] =   (in[1][X] * in[2][Y] - in[1][Y] * in[2][X]);
  584.   out[1][Z] = - (in[0][X] * in[2][Y] - in[0][Y] * in[2][X]);
  585.   out[2][Z] =   (in[0][X] * in[1][Y] - in[0][Y] * in[1][X]);
  586.  
  587.   det = in[0][X] * in[1][Y] * in[2][Z] +
  588.         in[0][Y] * in[1][Z] * in[2][X] +
  589.         in[0][Z] * in[1][X] * in[2][Y] -
  590.         in[0][Z] * in[1][Y] * in[2][X] -
  591.         in[0][X] * in[1][Z] * in[2][Y] -
  592.         in[0][Y] * in[1][X] * in[2][Z];
  593.  
  594.   if (fabs(det) < BEZIER_EPSILON)
  595.   {
  596.     return (0);
  597.   }
  598.  
  599.   det = 1.0 / det;
  600.  
  601.   for (i = 0; i < 3; i++)
  602.   {
  603.     VScaleEq(out[i], det)
  604.   }
  605.  
  606.   return (1);
  607. }
  608.  
  609.  
  610.  
  611. /*****************************************************************************
  612. *
  613. * FUNCTION
  614. *
  615. *   intersect_subpatch
  616. *
  617. * INPUT
  618. *
  619. * OUTPUT
  620. *
  621. * RETURNS
  622. *
  623. * AUTHOR
  624. *
  625. *   Alexander Enzmann
  626. *
  627. * DESCRIPTION
  628. *
  629. *   -
  630. *
  631. * CHANGES
  632. *
  633. *   -
  634. *
  635. ******************************************************************************/
  636.  
  637. static int intersect_subpatch(Shape, ray, V1, uu, vv, Depth, P, N, u, v)
  638. BICUBIC_PATCH *Shape;
  639. RAY *ray;
  640. VECTOR V1[3];
  641. DBL uu[3], vv[3], *Depth;
  642. VECTOR P, N;
  643. DBL *u, *v;
  644. {
  645.   DBL d, n, a, b, r;
  646.   VECTOR B[3], IB[3], NN[3], Q, T1;
  647.  
  648.   VSub(B[0], V1[1], V1[0]);
  649.   VSub(B[1], V1[2], V1[0]);
  650.  
  651.   VCross(B[2], B[0], B[1]);
  652.  
  653.   VDot(d, B[2], B[2]);
  654.  
  655.   if (d < BEZIER_EPSILON)
  656.   {
  657.     return (0);
  658.   }
  659.  
  660.   d = 1.0 / sqrt(d);
  661.  
  662.   VScaleEq(B[2], d);
  663.  
  664.   /* Degenerate triangle. */
  665.  
  666.   if (!InvertMatrix(B, IB))
  667.   {
  668.     return (0);
  669.   }
  670.  
  671.   VDot(d, ray->Direction, IB[2]);
  672.  
  673.   if (fabs(d) < BEZIER_EPSILON)
  674.   {
  675.     return (0);
  676.   }
  677.  
  678.   VSub(Q, V1[0], ray->Initial);
  679.  
  680.   VDot(n, Q, IB[2]);
  681.  
  682.   *Depth = n / d;
  683.  
  684.   if (*Depth < BEZIER_TOLERANCE)
  685.   {
  686.     return (0);
  687.   }
  688.  
  689.   VScale(T1, ray->Direction, *Depth);
  690.  
  691.   VAdd(P, ray->Initial, T1);
  692.  
  693.   VSub(Q, P, V1[0]);
  694.  
  695.   VDot(a, Q, IB[0]);
  696.   VDot(b, Q, IB[1]);
  697.  
  698.   if ((a < 0.0) || (b < 0.0) || (a + b > 1.0))
  699.   {
  700.     return (0);
  701.   }
  702.  
  703.   r = 1.0 - a - b;
  704.  
  705.   Make_Vector(N, 0.0, 0.0, 0.0);
  706.  
  707.   bezier_value((VECTOR(*)[4][4])&Shape->Control_Points, uu[0], vv[0], T1, NN[0]);
  708.   bezier_value((VECTOR(*)[4][4])&Shape->Control_Points, uu[1], vv[1], T1, NN[1]);
  709.   bezier_value((VECTOR(*)[4][4])&Shape->Control_Points, uu[2], vv[2], T1, NN[2]);
  710.  
  711.   VScale(T1, NN[0], r); VAddEq(N, T1);
  712.   VScale(T1, NN[1], a); VAddEq(N, T1);
  713.   VScale(T1, NN[2], b); VAddEq(N, T1);
  714.  
  715.   *u = r * uu[0] + a * uu[1] + b * uu[2];
  716.   *v = r * vv[0] + a * vv[1] + b * vv[2];
  717.  
  718.   VDot(d, N, N);
  719.  
  720.   if (d > BEZIER_EPSILON)
  721.   {
  722.     d = 1.0 / sqrt(d);
  723.  
  724.     VScaleEq(N, d);
  725.   }
  726.   else
  727.   {
  728.     Make_Vector(N, 1, 0, 0);
  729.   }
  730.  
  731.   return (1);
  732. }
  733.  
  734.  
  735.  
  736. /*****************************************************************************
  737. *
  738. * FUNCTION
  739. *
  740. *   find_average
  741. *
  742. * INPUT
  743. *
  744. * OUTPUT
  745. *
  746. * RETURNS
  747. *
  748. * AUTHOR
  749. *
  750. *   Alexander Enzmann
  751. *
  752. * DESCRIPTION
  753. *
  754. *   Find a sphere that contains all of the points in the list "vectors".
  755. *
  756. * CHANGES
  757. *
  758. *   -
  759. *
  760. ******************************************************************************/
  761.  
  762. static void find_average(vector_count, vectors, center, radius)
  763. int vector_count;
  764. VECTOR *vectors, center;
  765. DBL *radius;
  766. {
  767.   int i;
  768.   DBL r0, r1, xc = 0, yc = 0, zc = 0;
  769.   DBL x0, y0, z0;
  770.   DBL rdiv;
  771.  
  772.   for (i = 0; i < vector_count; i++)
  773.   {
  774.     xc += vectors[i][X];
  775.     yc += vectors[i][Y];
  776.     zc += vectors[i][Z];
  777.   }
  778.  
  779. /*
  780.   xc /= (DBL)vector_count;
  781.   yc /= (DBL)vector_count;
  782.   zc /= (DBL)vector_count;
  783. */
  784.   rdiv = (1 / (DBL)vector_count);
  785.   xc *= rdiv;
  786.   yc *= rdiv;
  787.   zc *= rdiv;
  788.  
  789.   r0 = 0.0;
  790.  
  791.   for (i = 0; i < vector_count; i++)
  792.   {
  793.     x0 = vectors[i][X] - xc;
  794.     y0 = vectors[i][Y] - yc;
  795.     z0 = vectors[i][Z] - zc;
  796.  
  797.     r1 = x0 * x0 + y0 * y0 + z0 * z0;
  798.  
  799.     if (r1 > r0)
  800.     {
  801.       r0 = r1;
  802.     }
  803.   }
  804.  
  805.   Make_Vector(center, xc, yc, zc);
  806.  
  807.   *radius = r0;
  808. }
  809.  
  810.  
  811.  
  812. /*****************************************************************************
  813. *
  814. * FUNCTION
  815. *
  816. *   spherical_bounds_check
  817. *
  818. * INPUT
  819. *
  820. * OUTPUT
  821. *
  822. * RETURNS
  823. *
  824. * AUTHOR
  825. *
  826. *   Alexander Enzmann
  827. *
  828. * DESCRIPTION
  829. *
  830. *   -
  831. *
  832. * CHANGES
  833. *
  834. *   -
  835. *
  836. ******************************************************************************/
  837.  
  838. static int spherical_bounds_check(Ray, center, radius)
  839. RAY *Ray;
  840. VECTOR center;
  841. DBL radius;
  842. {
  843.   DBL x, y, z, dist1, dist2;
  844.  
  845.   x = center[X] - Ray->Initial[X];
  846.   y = center[Y] - Ray->Initial[Y];
  847.   z = center[Z] - Ray->Initial[Z];
  848.  
  849.   dist1 = x * x + y * y + z * z;
  850.  
  851.   if (dist1 < radius)
  852.   {
  853.     /* ray starts inside sphere - assume it intersects. */
  854.  
  855.     return (1);
  856.   }
  857.   else
  858.   {
  859.     dist2 = x*Ray->Direction[X] + y*Ray->Direction[Y] + z*Ray->Direction[Z];
  860.  
  861.     dist2 *= dist2;
  862.  
  863.     if ((dist2 > 0) && (dist1 - dist2 < radius))
  864.     {
  865.       return (1);
  866.     }
  867.   }
  868.  
  869.   return (0);
  870. }
  871.  
  872.  
  873.  
  874. /*****************************************************************************
  875. *
  876. * FUNCTION
  877. *
  878. *   bezier_bounding_sphere
  879. *
  880. * INPUT
  881. *
  882. * OUTPUT
  883. *
  884. * RETURNS
  885. *
  886. * AUTHOR
  887. *
  888. *   Alexander Enzmann
  889. *
  890. * DESCRIPTION
  891. *
  892. *   Find a sphere that bounds all of the control points of a Bezier patch.
  893. *   The values returned are: the center of the bounding sphere, and the
  894. *   square of the radius of the bounding sphere.
  895. *
  896. * CHANGES
  897. *
  898. *   -
  899. *
  900. ******************************************************************************/
  901.  
  902. static void bezier_bounding_sphere(Patch, center, radius)
  903. VECTOR(*Patch)[4][4], center;
  904. DBL *radius;
  905. {
  906.   int i, j;
  907.   DBL r0, r1, xc = 0, yc = 0, zc = 0;
  908.   DBL x0, y0, z0;
  909.  
  910.   for (i = 0; i < 4; i++)
  911.   {
  912.     for (j = 0; j < 4; j++)
  913.     {
  914.       xc += (*Patch)[i][j][X];
  915.       yc += (*Patch)[i][j][Y];
  916.       zc += (*Patch)[i][j][Z];
  917.     }
  918.   }
  919.  
  920.   xc /= 16.0;
  921.   yc /= 16.0;
  922.   zc /= 16.0;
  923.  
  924.   r0 = 0.0;
  925.  
  926.   for (i = 0; i < 4; i++)
  927.   {
  928.     for (j = 0; j < 4; j++)
  929.     {
  930.       x0 = (*Patch)[i][j][X] - xc;
  931.       y0 = (*Patch)[i][j][Y] - yc;
  932.       z0 = (*Patch)[i][j][Z] - zc;
  933.  
  934.       r1 = x0 * x0 + y0 * y0 + z0 * z0;
  935.  
  936.       if (r1 > r0)
  937.       {
  938.         r0 = r1;
  939.       }
  940.     }
  941.   }
  942.  
  943.   Make_Vector(center, xc, yc, zc);
  944.  
  945.   *radius = r0;
  946. }
  947.  
  948.  
  949.  
  950. /*****************************************************************************
  951. *
  952. * FUNCTION
  953. *
  954. *   Precompute_Patch_Values
  955. *
  956. * INPUT
  957. *
  958. * OUTPUT
  959. *
  960. * RETURNS
  961. *
  962. * AUTHOR
  963. *
  964. *   Alexander Enzmann
  965. *
  966. * DESCRIPTION
  967. *
  968. *   Precompute grid points and normals for a bezier patch.
  969. *
  970. * CHANGES
  971. *
  972. *   -
  973. *
  974. ******************************************************************************/
  975.  
  976. void Precompute_Patch_Values(Shape)
  977. BICUBIC_PATCH *Shape;
  978. {
  979.   int i, j;
  980.   VECTOR Control_Points[16];
  981.   VECTOR(*Patch_Ptr)[4][4] = (VECTOR(*)[4][4]) Shape->Control_Points;
  982.  
  983.   /* Calculate the bounding sphere for the entire patch. */
  984.  
  985.   for (i = 0; i < 4; i++)
  986.   {
  987.     for (j = 0; j < 4; j++)
  988.     {
  989.       Assign_Vector(Control_Points[4*i + j], Shape->Control_Points[i][j]);
  990.     }
  991.   }
  992.  
  993.   find_average(16, Control_Points, Shape->Bounding_Sphere_Center, &Shape->Bounding_Sphere_Radius);
  994.  
  995.   if (Shape->Patch_Type != 0)
  996.   {
  997.     if (Shape->Node_Tree != NULL)
  998.     {
  999.       bezier_tree_deleter(Shape->Node_Tree);
  1000.     }
  1001.  
  1002.     Shape->Node_Tree = bezier_tree_builder(Shape, Patch_Ptr, 0.0, 1.0, 0.0, 1.0, 0);
  1003.   }
  1004. }
  1005.  
  1006.  
  1007.  
  1008. /*****************************************************************************
  1009. *
  1010. * FUNCTION
  1011. *
  1012. *   point_plane_distance
  1013. *
  1014. * INPUT
  1015. *
  1016. * OUTPUT
  1017. *
  1018. * RETURNS
  1019. *
  1020. * AUTHOR
  1021. *
  1022. *   Alexander Enzmann
  1023. *
  1024. * DESCRIPTION
  1025. *
  1026. *   Determine the distance from a point to a plane.
  1027. *
  1028. * CHANGES
  1029. *
  1030. *   -
  1031. *
  1032. ******************************************************************************/
  1033.  
  1034. static DBL point_plane_distance(p, n, d)
  1035. VECTOR p, n;
  1036. DBL *d;
  1037. {
  1038.   DBL temp1, temp2;
  1039.  
  1040.   VDot(temp1, p, n);
  1041.  
  1042.   temp1 += *d;
  1043.  
  1044.   VLength(temp2, n);
  1045.  
  1046.   if (fabs(temp2) < EPSILON)
  1047.   {
  1048.     return (0.0);
  1049.   }
  1050.  
  1051.   temp1 /= temp2;
  1052.  
  1053.   return (temp1);
  1054. }
  1055.  
  1056.  
  1057.  
  1058. /*****************************************************************************
  1059. *
  1060. * FUNCTION
  1061. *
  1062. *   bezier_subpatch_intersect
  1063. *
  1064. * INPUT
  1065. *
  1066. * OUTPUT
  1067. *
  1068. * RETURNS
  1069. *
  1070. * AUTHOR
  1071. *
  1072. *   Alexander Enzmann
  1073. *
  1074. * DESCRIPTION
  1075. *
  1076. *   -
  1077. *
  1078. * CHANGES
  1079. *
  1080. *   -
  1081. *
  1082. ******************************************************************************/
  1083.  
  1084. static int bezier_subpatch_intersect(ray, Shape, Patch, u0, u1, v0, v1, Depth_Stack)
  1085. RAY *ray;
  1086. BICUBIC_PATCH *Shape;
  1087. VECTOR(*Patch)[4][4];
  1088. DBL u0, u1, v0, v1;
  1089. ISTACK *Depth_Stack;
  1090. {
  1091.   int cnt = 0;
  1092.   VECTOR V1[3];
  1093.   DBL u, v, Depth, uu[3], vv[3];
  1094.   VECTOR P, N;
  1095.  
  1096.   Assign_Vector(V1[0], (*Patch)[0][0]);
  1097.   Assign_Vector(V1[1], (*Patch)[0][3]);
  1098.   Assign_Vector(V1[2], (*Patch)[3][3]);
  1099.  
  1100.   uu[0] = u0; uu[1] = u0; uu[2] = u1;
  1101.   vv[0] = v0; vv[1] = v1; vv[2] = v1;
  1102.  
  1103.   if (intersect_subpatch(Shape, ray, V1, uu, vv, &Depth, P, N, &u, &v))
  1104.   {
  1105.     push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  1106.  
  1107.     cnt++;
  1108.   }
  1109.  
  1110.   Assign_Vector(V1[1], V1[2]);
  1111.   Assign_Vector(V1[2], (*Patch)[3][0]);
  1112.  
  1113.   uu[1] = uu[2]; uu[2] = u1;
  1114.   vv[1] = vv[2]; vv[2] = v0;
  1115.  
  1116.   if (intersect_subpatch(Shape, ray, V1, uu, vv, &Depth, P, N, &u, &v))
  1117.   {
  1118.     push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  1119.  
  1120.     cnt++;
  1121.   }
  1122.  
  1123.   return (cnt);
  1124. }
  1125.  
  1126.  
  1127.  
  1128.  
  1129. /*****************************************************************************
  1130. *
  1131. * FUNCTION
  1132. *
  1133. *   bezier_split_left_right
  1134. *
  1135. * INPUT
  1136. *
  1137. * OUTPUT
  1138. *
  1139. * RETURNS
  1140. *
  1141. * AUTHOR
  1142. *
  1143. *   Alexander Enzmann
  1144. *
  1145. * DESCRIPTION
  1146. *
  1147. *   -
  1148. *
  1149. * CHANGES
  1150. *
  1151. *   -
  1152. *
  1153. ******************************************************************************/
  1154.  
  1155. static void bezier_split_left_right(Patch, Left_Patch, Right_Patch)
  1156. VECTOR(*Patch)[4][4], (*Left_Patch)[4][4], (*Right_Patch)[4][4];
  1157. {
  1158.   int i, j;
  1159.   VECTOR Temp1[4], Temp2[4], Half;
  1160.  
  1161.   for (i = 0; i < 4; i++)
  1162.   {
  1163.     Assign_Vector(Temp1[0], (*Patch)[0][i]);
  1164.  
  1165.     VHalf(Temp1[1], (*Patch)[0][i], (*Patch)[1][i]);
  1166.     VHalf(Half, (*Patch)[1][i], (*Patch)[2][i]);
  1167.     VHalf(Temp1[2], Temp1[1], Half);
  1168.     VHalf(Temp2[2], (*Patch)[2][i], (*Patch)[3][i]);
  1169.     VHalf(Temp2[1], Half, Temp2[2]);
  1170.     VHalf(Temp1[3], Temp1[2], Temp2[1]);
  1171.  
  1172.     Assign_Vector(Temp2[0], Temp1[3]);
  1173.     Assign_Vector(Temp2[3], (*Patch)[3][i]);
  1174.  
  1175.     for (j = 0; j < 4; j++)
  1176.     {
  1177.       Assign_Vector((*Left_Patch)[j][i], Temp1[j]);
  1178.       Assign_Vector((*Right_Patch)[j][i], Temp2[j]);
  1179.     }
  1180.   }
  1181. }
  1182.  
  1183.  
  1184.  
  1185. /*****************************************************************************
  1186. *
  1187. * FUNCTION
  1188. *
  1189. *   bezier_split_up_down
  1190. *
  1191. * INPUT
  1192. *
  1193. * OUTPUT
  1194. *
  1195. * RETURNS
  1196. *
  1197. * AUTHOR
  1198. *
  1199. *   Alexander Enzmann
  1200. *
  1201. * DESCRIPTION
  1202. *
  1203. *   -
  1204. *
  1205. * CHANGES
  1206. *
  1207. *   -
  1208. *
  1209. ******************************************************************************/
  1210.  
  1211. static void bezier_split_up_down(Patch, Bottom_Patch, Top_Patch)
  1212. VECTOR(*Patch)[4][4], (*Top_Patch)[4][4], (*Bottom_Patch)[4][4];
  1213. {
  1214.   int i, j;
  1215.   VECTOR Temp1[4], Temp2[4], Half;
  1216.  
  1217.   for (i = 0; i < 4; i++)
  1218.   {
  1219.     Assign_Vector(Temp1[0], (*Patch)[i][0]);
  1220.  
  1221.     VHalf(Temp1[1], (*Patch)[i][0], (*Patch)[i][1]);
  1222.     VHalf(Half, (*Patch)[i][1], (*Patch)[i][2]);
  1223.     VHalf(Temp1[2], Temp1[1], Half);
  1224.     VHalf(Temp2[2], (*Patch)[i][2], (*Patch)[i][3]);
  1225.     VHalf(Temp2[1], Half, Temp2[2]);
  1226.     VHalf(Temp1[3], Temp1[2], Temp2[1]);
  1227.  
  1228.     Assign_Vector(Temp2[0], Temp1[3]);
  1229.     Assign_Vector(Temp2[3], (*Patch)[i][3]);
  1230.  
  1231.     for (j = 0; j < 4; j++)
  1232.     {
  1233.       Assign_Vector((*Bottom_Patch)[i][j], Temp1[j]);
  1234.       Assign_Vector((*Top_Patch)[i][j]   , Temp2[j]);
  1235.     }
  1236.   }
  1237. }
  1238.  
  1239.  
  1240.  
  1241. /*****************************************************************************
  1242. *
  1243. * FUNCTION
  1244. *
  1245. *   determine_subpatch_flatness
  1246. *
  1247. * INPUT
  1248. *
  1249. * OUTPUT
  1250. *
  1251. * RETURNS
  1252. *
  1253. * AUTHOR
  1254. *
  1255. *   Alexander Enzmann
  1256. *
  1257. * DESCRIPTION
  1258. *
  1259. *   See how close to a plane a subpatch is, the patch must have at least
  1260. *   three distinct vertices. A negative result from this function indicates
  1261. *   that a degenerate value of some sort was encountered.
  1262. *
  1263. * CHANGES
  1264. *
  1265. *   -
  1266. *
  1267. ******************************************************************************/
  1268.  
  1269. static DBL determine_subpatch_flatness(Patch)
  1270. VECTOR(*Patch)[4][4];
  1271. {
  1272.   int i, j;
  1273.   DBL d, dist, temp1;
  1274.   VECTOR vertices[4], n, TempV;
  1275.  
  1276.   Assign_Vector(vertices[0], (*Patch)[0][0]);
  1277.   Assign_Vector(vertices[1], (*Patch)[0][3]);
  1278.  
  1279.   VSub(TempV, vertices[0], vertices[1]);
  1280.  
  1281.   VLength(temp1, TempV);
  1282.  
  1283.   if (fabs(temp1) < EPSILON)
  1284.   {
  1285.     /*
  1286.      * Degenerate in the V direction for U = 0. This is ok if the other
  1287.      * two corners are distinct from the lower left corner - I'm sure there
  1288.      * are cases where the corners coincide and the middle has good values,
  1289.      * but that is somewhat pathalogical and won't be considered.
  1290.      */
  1291.  
  1292.     Assign_Vector(vertices[1], (*Patch)[3][3]);
  1293.  
  1294.     VSub(TempV, vertices[0], vertices[1]);
  1295.  
  1296.     VLength(temp1, TempV);
  1297.  
  1298.     if (fabs(temp1) < EPSILON)
  1299.     {
  1300.       return (-1.0);
  1301.     }
  1302.  
  1303.     Assign_Vector(vertices[2], (*Patch)[3][0]);
  1304.  
  1305.     VSub(TempV, vertices[0], vertices[1]);
  1306.  
  1307.     VLength(temp1, TempV);
  1308.  
  1309.     if (fabs(temp1) < EPSILON)
  1310.     {
  1311.       return (-1.0);
  1312.     }
  1313.  
  1314.     VSub(TempV, vertices[1], vertices[2]);
  1315.  
  1316.     VLength(temp1, TempV);
  1317.  
  1318.     if (fabs(temp1) < EPSILON)
  1319.     {
  1320.       return (-1.0);
  1321.     }
  1322.   }
  1323.   else
  1324.   {
  1325.     Assign_Vector(vertices[2], (*Patch)[3][0]);
  1326.  
  1327.     VSub(TempV, vertices[0], vertices[1]);
  1328.  
  1329.     VLength(temp1, TempV);
  1330.  
  1331.     if (fabs(temp1) < EPSILON)
  1332.     {
  1333.       Assign_Vector(vertices[2], (*Patch)[3][3]);
  1334.  
  1335.       VSub(TempV, vertices[0], vertices[2]);
  1336.  
  1337.       VLength(temp1, TempV);
  1338.  
  1339.       if (fabs(temp1) < EPSILON)
  1340.       {
  1341.         return (-1.0);
  1342.       }
  1343.  
  1344.       VSub(TempV, vertices[1], vertices[2]);
  1345.  
  1346.       VLength(temp1, TempV);
  1347.  
  1348.       if (fabs(temp1) < EPSILON)
  1349.       {
  1350.         return (-1.0);
  1351.       }
  1352.     }
  1353.     else
  1354.     {
  1355.       VSub(TempV, vertices[1], vertices[2]);
  1356.  
  1357.       VLength(temp1, TempV);
  1358.  
  1359.       if (fabs(temp1) < EPSILON)
  1360.       {
  1361.         return (-1.0);
  1362.       }
  1363.     }
  1364.   }
  1365.  
  1366.   /*
  1367.    * Now that a good set of candidate points has been found,
  1368.    * find the plane equations for the patch.
  1369.    */
  1370.  
  1371.   if (subpatch_normal(vertices[0], vertices[1], vertices[2], n, &d))
  1372.   {
  1373.     /*
  1374.      * Step through all vertices and see what the maximum
  1375.      * distance from the plane happens to be.
  1376.      */
  1377.  
  1378.     dist = 0.0;
  1379.  
  1380.     for (i = 0; i < 4; i++)
  1381.     {
  1382.       for (j = 0; j < 4; j++)
  1383.       {
  1384.         temp1 = fabs(point_plane_distance(((*Patch)[i][j]), n, &d));
  1385.  
  1386.         if (temp1 > dist)
  1387.         {
  1388.           dist = temp1;
  1389.         }
  1390.       }
  1391.     }
  1392.  
  1393.     return (dist);
  1394.   }
  1395.   else
  1396.   {
  1397. /*
  1398.     Debug_Info("Subpatch normal failed in determine_subpatch_flatness\n");
  1399. */
  1400.  
  1401.     return (-1.0);
  1402.   }
  1403. }
  1404.  
  1405.  
  1406.  
  1407. /*****************************************************************************
  1408. *
  1409. * FUNCTION
  1410. *
  1411. *   flat_enough
  1412. *
  1413. * INPUT
  1414. *
  1415. * OUTPUT
  1416. *
  1417. * RETURNS
  1418. *
  1419. * AUTHOR
  1420. *
  1421. *   Alexander Enzmann
  1422. *
  1423. * DESCRIPTION
  1424. *
  1425. *   -
  1426. *
  1427. * CHANGES
  1428. *
  1429. *   -
  1430. *
  1431. ******************************************************************************/
  1432.  
  1433. static int flat_enough(Object, Patch)
  1434. BICUBIC_PATCH *Object;
  1435. VECTOR(*Patch)[4][4];
  1436. {
  1437.   DBL Dist;
  1438.  
  1439.   Dist = determine_subpatch_flatness(Patch);
  1440.  
  1441.   if (Dist < 0.0)
  1442.   {
  1443.     return (0);
  1444.   }
  1445.   else
  1446.   {
  1447.     if (Dist < Object->Flatness_Value)
  1448.     {
  1449.       return (1);
  1450.     }
  1451.     else
  1452.     {
  1453.       return (0);
  1454.     }
  1455.   }
  1456. }
  1457.  
  1458.  
  1459.  
  1460. /*****************************************************************************
  1461. *
  1462. * FUNCTION
  1463. *
  1464. *   bezier_subdivider
  1465. *
  1466. * INPUT
  1467. *
  1468. * OUTPUT
  1469. *
  1470. * RETURNS
  1471. *
  1472. * AUTHOR
  1473. *
  1474. *   Alexander Enzmann
  1475. *
  1476. * DESCRIPTION
  1477. *
  1478. *   -
  1479. *
  1480. * CHANGES
  1481. *
  1482. *   -
  1483. *
  1484. ******************************************************************************/
  1485.  
  1486. static int bezier_subdivider(Ray, Object, Patch, u0, u1, v0, v1,
  1487. recursion_depth, Depth_Stack)
  1488. RAY *Ray;
  1489. BICUBIC_PATCH *Object;
  1490. VECTOR(*Patch)[4][4];
  1491. DBL u0, u1, v0, v1;
  1492. int recursion_depth;
  1493. ISTACK *Depth_Stack;
  1494. {
  1495.   int cnt = 0;
  1496.   DBL ut, vt, radius;
  1497.   VECTOR Lower_Left[4][4], Lower_Right[4][4];
  1498.   VECTOR Upper_Left[4][4], Upper_Right[4][4];
  1499.   VECTOR center;
  1500.  
  1501.   /*
  1502.    * Make sure the ray passes through a sphere bounding
  1503.    * the control points of the patch.
  1504.    */
  1505.  
  1506.   bezier_bounding_sphere(Patch, center, &radius);
  1507.  
  1508.   if (!spherical_bounds_check(Ray, center, radius))
  1509.   {
  1510.     return (0);
  1511.   }
  1512.  
  1513.   /*
  1514.    * If the patch is close to being flat, then just
  1515.    * perform a ray-plane intersection test.
  1516.    */
  1517.  
  1518.   if (flat_enough(Object, Patch))
  1519.   {
  1520.     return bezier_subpatch_intersect(Ray, Object, Patch, u0, u1, v0, v1, Depth_Stack);
  1521.   }
  1522.  
  1523.   if (recursion_depth >= Object->U_Steps)
  1524.   {
  1525.     if (recursion_depth >= Object->V_Steps)
  1526.     {
  1527.       return bezier_subpatch_intersect(Ray, Object, Patch, u0, u1, v0, v1, Depth_Stack);
  1528.     }
  1529.     else
  1530.     {
  1531.       bezier_split_up_down(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left);
  1532.  
  1533.       vt = (v1 - v0) / 2.0;
  1534.  
  1535.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Left, u0, u1, v0, vt, recursion_depth + 1, Depth_Stack);
  1536.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Upper_Left, u0, u1, vt, v1, recursion_depth + 1, Depth_Stack);
  1537.     }
  1538.   }
  1539.   else
  1540.   {
  1541.     if (recursion_depth >= Object->V_Steps)
  1542.     {
  1543.       bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  1544.  
  1545.       ut = (u1 - u0) / 2.0;
  1546.  
  1547.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Left, u0, ut, v0, v1, recursion_depth + 1, Depth_Stack);
  1548.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Right, ut, u1, v0, v1, recursion_depth + 1, Depth_Stack);
  1549.     }
  1550.     else
  1551.     {
  1552.       ut = (u1 - u0) / 2.0;
  1553.       vt = (v1 - v0) / 2.0;
  1554.  
  1555.       bezier_split_left_right(Patch, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Right);
  1556.       bezier_split_up_down((VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Lower_Left, (VECTOR(*)[4][4])Upper_Left) ;
  1557.       bezier_split_up_down((VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Lower_Right, (VECTOR(*)[4][4])Upper_Right);
  1558.  
  1559.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Left, u0, ut, v0, vt, recursion_depth + 1, Depth_Stack);
  1560.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Upper_Left, u0, ut, vt, v1, recursion_depth + 1, Depth_Stack);
  1561.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Lower_Right, ut, u1, v0, vt, recursion_depth + 1, Depth_Stack);
  1562.       cnt += bezier_subdivider(Ray, Object, (VECTOR(*)[4][4])Upper_Right, ut, u1, vt, v1, recursion_depth + 1, Depth_Stack);
  1563.     }
  1564.   }
  1565.  
  1566.   return (cnt);
  1567. }
  1568.  
  1569.  
  1570.  
  1571. /*****************************************************************************
  1572. *
  1573. * FUNCTION
  1574. *
  1575. *   bezier_tree_deleter
  1576. *
  1577. * INPUT
  1578. *
  1579. * OUTPUT
  1580. *
  1581. * RETURNS
  1582. *
  1583. * AUTHOR
  1584. *
  1585. *   Alexander Enzmann
  1586. *
  1587. * DESCRIPTION
  1588. *
  1589. *   -
  1590. *
  1591. * CHANGES
  1592. *
  1593. *   -
  1594. *
  1595. ******************************************************************************/
  1596.  
  1597. static void bezier_tree_deleter(Node)
  1598. BEZIER_NODE *Node;
  1599. {
  1600.   int i;
  1601.   BEZIER_CHILDREN *Children;
  1602.  
  1603.   /* If this is an interior node then continue the descent. */
  1604.  
  1605.   if (Node->Node_Type == BEZIER_INTERIOR_NODE)
  1606.   {
  1607.     Children = (BEZIER_CHILDREN *)Node->Data_Ptr;
  1608.  
  1609.     for (i = 0; i < Node->Count; i++)
  1610.     {
  1611.       bezier_tree_deleter(Children->Children[i]);
  1612.     }
  1613.  
  1614.     POV_FREE(Children);
  1615.   }
  1616.   else
  1617.   {
  1618.     if (Node->Node_Type == BEZIER_LEAF_NODE)
  1619.     {
  1620.       /* Free the memory used for the vertices. */
  1621.  
  1622.       POV_FREE(Node->Data_Ptr);
  1623.     }
  1624.   }
  1625.  
  1626.   /* Free the memory used for the node. */
  1627.  
  1628.   POV_FREE(Node);
  1629. }
  1630.  
  1631.  
  1632.  
  1633. /*****************************************************************************
  1634. *
  1635. * FUNCTION
  1636. *
  1637. *   bezier_tree_walker
  1638. *
  1639. * INPUT
  1640. *
  1641. * OUTPUT
  1642. *
  1643. * RETURNS
  1644. *
  1645. * AUTHOR
  1646. *
  1647. *   Alexander Enzmann
  1648. *
  1649. * DESCRIPTION
  1650. *
  1651. *   -
  1652. *
  1653. * CHANGES
  1654. *
  1655. *   -
  1656. *
  1657. ******************************************************************************/
  1658.  
  1659. static int bezier_tree_walker(Ray, Shape, Node, Depth_Stack)
  1660. RAY *Ray;
  1661. BICUBIC_PATCH *Shape;
  1662. BEZIER_NODE *Node;
  1663. ISTACK *Depth_Stack;
  1664. {
  1665.   int i, cnt = 0;
  1666.   DBL Depth, u, v, uu[3], vv[3];
  1667.   VECTOR N, P, V1[3];
  1668.   BEZIER_CHILDREN *Children;
  1669.   BEZIER_VERTICES *Vertices;
  1670.  
  1671.   /*
  1672.    * Make sure the ray passes through a sphere bounding
  1673.    * the control points of the patch.
  1674.    */
  1675.  
  1676.   if (!spherical_bounds_check(Ray, Node->Center, Node->Radius_Squared))
  1677.   {
  1678.     return (0);
  1679.   }
  1680.  
  1681.   /*
  1682.    * If this is an interior node then continue the descent,
  1683.    * else do a check against the vertices.
  1684.    */
  1685.  
  1686.   if (Node->Node_Type == BEZIER_INTERIOR_NODE)
  1687.   {
  1688.     Children = (BEZIER_CHILDREN *)Node->Data_Ptr;
  1689.  
  1690.     for (i = 0; i < Node->Count; i++)
  1691.     {
  1692.       cnt += bezier_tree_walker(Ray, Shape, Children->Children[i], Depth_Stack);
  1693.     }
  1694.   }
  1695.   else if (Node->Node_Type == BEZIER_LEAF_NODE)
  1696.   {
  1697.     Vertices = (BEZIER_VERTICES *)Node->Data_Ptr;
  1698.  
  1699.     Assign_Vector(V1[0], Vertices->Vertices[0]);
  1700.     Assign_Vector(V1[1], Vertices->Vertices[1]);
  1701.     Assign_Vector(V1[2], Vertices->Vertices[2]);
  1702.  
  1703.     uu[0] = Vertices->uvbnds[0];
  1704.     uu[1] = Vertices->uvbnds[0];
  1705.     uu[2] = Vertices->uvbnds[1];
  1706.     vv[0] = Vertices->uvbnds[2];
  1707.     vv[1] = Vertices->uvbnds[3];
  1708.     vv[2] = Vertices->uvbnds[3];
  1709.  
  1710.     /*
  1711.      * Triangulate this subpatch, then check for
  1712.      * intersections in the triangles.
  1713.      */
  1714.  
  1715.     if (intersect_subpatch(Shape, Ray, V1, uu, vv, &Depth, P, N, &u, &v))
  1716.     {
  1717.       push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  1718.  
  1719.       cnt++;
  1720.     }
  1721.  
  1722.     Assign_Vector(V1[1], V1[2]);
  1723.     Assign_Vector(V1[2], Vertices->Vertices[3]);
  1724.  
  1725.     uu[1] = uu[2]; uu[2] = Vertices->uvbnds[1];
  1726.     vv[1] = vv[2]; vv[2] = Vertices->uvbnds[2];
  1727.  
  1728.     if (intersect_subpatch(Shape, Ray, V1, uu, vv, &Depth, P, N, &u, &v))
  1729.     {
  1730.       push_normal_entry(Depth, P, N, (OBJECT *)Shape, Depth_Stack);
  1731.  
  1732.       cnt++;
  1733.     }
  1734.   }
  1735.   else
  1736.   {
  1737.     Error("Bad Node type in bezier_tree_walker().\n");
  1738.   }
  1739.  
  1740.   return (cnt);
  1741. }
  1742.  
  1743.  
  1744.  
  1745. /*****************************************************************************
  1746. *
  1747. * FUNCTION
  1748. *
  1749. *   intersect_bicubic_patch0
  1750. *
  1751. * INPUT
  1752. *
  1753. * OUTPUT
  1754. *
  1755. * RETURNS
  1756. *
  1757. * AUTHOR
  1758. *
  1759. *   Alexander Enzmann
  1760. *
  1761. * DESCRIPTION
  1762. *
  1763. *   -
  1764. *
  1765. * CHANGES
  1766. *
  1767. *   -
  1768. *
  1769. ******************************************************************************/
  1770.  
  1771. static int intersect_bicubic_patch0(Ray, Shape, Depth_Stack)
  1772. RAY *Ray;
  1773. BICUBIC_PATCH *Shape;
  1774. ISTACK *Depth_Stack;
  1775. {
  1776.   VECTOR(*Patch)[4][4] = (VECTOR(*)[4][4]) Shape->Control_Points;
  1777.   
  1778.   return (bezier_subdivider(Ray, Shape, Patch, 0.0, 1.0, 0.0, 1.0, 0, Depth_Stack));
  1779. }
  1780.  
  1781.  
  1782.  
  1783. /*****************************************************************************
  1784. *
  1785. * FUNCTION
  1786. *
  1787. *   All_Bicubic_Patch_Intersections
  1788. *
  1789. * INPUT
  1790. *   
  1791. * OUTPUT
  1792. *   
  1793. * RETURNS
  1794. *   
  1795. * AUTHOR
  1796. *
  1797. *   Alexander Enzmann
  1798. *   
  1799. * DESCRIPTION
  1800. *
  1801. *   -
  1802. *
  1803. * CHANGES
  1804. *
  1805. *   -
  1806. *
  1807. ******************************************************************************/
  1808.  
  1809. static int All_Bicubic_Patch_Intersections(Object, Ray, Depth_Stack)
  1810. OBJECT *Object;
  1811. RAY *Ray;
  1812. ISTACK *Depth_Stack;
  1813. {
  1814.   int Found, cnt = 0;
  1815.  
  1816.   Found = FALSE;
  1817.  
  1818.   Increase_Counter(stats[Ray_Bicubic_Tests]);
  1819.  
  1820.   switch (((BICUBIC_PATCH *)Object)->Patch_Type)
  1821.   {
  1822.     case 0:
  1823.  
  1824.       cnt = intersect_bicubic_patch0(Ray, ((BICUBIC_PATCH *)Object), Depth_Stack);
  1825.  
  1826.       break;
  1827.  
  1828.     case 1:
  1829.  
  1830.       cnt = bezier_tree_walker(Ray, (BICUBIC_PATCH *)Object, ((BICUBIC_PATCH *)Object)->Node_Tree, Depth_Stack);
  1831.  
  1832.       break;
  1833.  
  1834.     default:
  1835.  
  1836.       Error("Bad patch type in All_Bicubic_Patch_Intersections.\n");
  1837.   }
  1838.   
  1839.   if (cnt > 0)
  1840.   {
  1841.     Increase_Counter(stats[Ray_Bicubic_Tests_Succeeded]);
  1842.     
  1843.     Found = TRUE;
  1844.   }
  1845.   
  1846.   return (Found);
  1847. }
  1848.  
  1849.  
  1850.  
  1851. /*****************************************************************************
  1852. *
  1853. * FUNCTION
  1854. *
  1855. *   Inside_Bicubic_Patch
  1856. *
  1857. * INPUT
  1858. *   
  1859. * OUTPUT
  1860. *   
  1861. * RETURNS
  1862. *   
  1863. * AUTHOR
  1864. *
  1865. *   Alexander Enzmann
  1866. *   
  1867. * DESCRIPTION
  1868. *
  1869. *   A patch is not a solid, so an inside test doesn't make sense.
  1870. *
  1871. * CHANGES
  1872. *
  1873. *   -
  1874. *
  1875. ******************************************************************************/
  1876.  
  1877. static int Inside_Bicubic_Patch(IPoint, Object)
  1878. VECTOR IPoint;
  1879. OBJECT *Object;
  1880. {
  1881.   return (0);
  1882. }
  1883.  
  1884.  
  1885.  
  1886. /*****************************************************************************
  1887. *
  1888. * FUNCTION
  1889. *
  1890. *   Bicubic_Patch_Normal
  1891. *
  1892. * INPUT
  1893. *   
  1894. * OUTPUT
  1895. *   
  1896. * RETURNS
  1897. *   
  1898. * AUTHOR
  1899. *
  1900. *   Alexander Enzmann
  1901. *   
  1902. * DESCRIPTION
  1903. *
  1904. *   -
  1905. *
  1906. * CHANGES
  1907. *
  1908. *   -
  1909. *
  1910. ******************************************************************************/
  1911.  
  1912. static void Bicubic_Patch_Normal(Result, Object, Inter)
  1913. OBJECT *Object;
  1914. VECTOR Result;
  1915. INTERSECTION *Inter;
  1916. {
  1917.   /* Use preocmputed normal. */
  1918.  
  1919.   Assign_Vector(Result, Inter->INormal);
  1920. }
  1921.  
  1922.  
  1923.  
  1924. /*****************************************************************************
  1925. *
  1926. * FUNCTION
  1927. *
  1928. *   Translate_Bicubic_Patch
  1929. *
  1930. * INPUT
  1931. *   
  1932. * OUTPUT
  1933. *   
  1934. * RETURNS
  1935. *   
  1936. * AUTHOR
  1937. *
  1938. *   Alexander Enzmann
  1939. *   
  1940. * DESCRIPTION
  1941. *
  1942. *   -
  1943. *
  1944. * CHANGES
  1945. *
  1946. *   -
  1947. *
  1948. ******************************************************************************/
  1949.  
  1950. static void Translate_Bicubic_Patch(Object, Vector, Trans)
  1951. OBJECT *Object;
  1952. VECTOR Vector;
  1953. TRANSFORM *Trans;
  1954. {
  1955.   int i, j;
  1956.   BICUBIC_PATCH *Patch = (BICUBIC_PATCH *) Object;
  1957.  
  1958.   for (i = 0; i < 4; i++)
  1959.   {
  1960.     for (j = 0; j < 4; j++)
  1961.     {
  1962.       VAdd(Patch->Control_Points[i][j], Patch->Control_Points[i][j], Vector)
  1963.     }
  1964.   }
  1965.  
  1966.   Precompute_Patch_Values(Patch);
  1967.  
  1968.   Compute_Bicubic_Patch_BBox(Patch);
  1969. }
  1970.  
  1971.  
  1972.  
  1973. /*****************************************************************************
  1974. *
  1975. * FUNCTION
  1976. *
  1977. *   Rotate_Bicubic_Patch
  1978. *
  1979. * INPUT
  1980. *   
  1981. * OUTPUT
  1982. *   
  1983. * RETURNS
  1984. *   
  1985. * AUTHOR
  1986. *
  1987. *   Alexander Enzmann
  1988. *   
  1989. * DESCRIPTION
  1990. *
  1991. *   -
  1992. *
  1993. * CHANGES
  1994. *
  1995. *   -
  1996. *
  1997. ******************************************************************************/
  1998.  
  1999. static void Rotate_Bicubic_Patch(Object, Vector, Trans)
  2000. OBJECT *Object;
  2001. VECTOR Vector;
  2002. TRANSFORM *Trans;
  2003. {
  2004.   Transform_Bicubic_Patch(Object, Trans);
  2005. }
  2006.  
  2007.  
  2008.  
  2009. /*****************************************************************************
  2010. *
  2011. * FUNCTION
  2012. *
  2013. *   Scale_Bicubic_Patch
  2014. *
  2015. * INPUT
  2016. *   
  2017. * OUTPUT
  2018. *   
  2019. * RETURNS
  2020. *   
  2021. * AUTHOR
  2022. *
  2023. *   Alexander Enzmann
  2024. *   
  2025. * DESCRIPTION
  2026. *
  2027. *   -
  2028. *
  2029. * CHANGES
  2030. *
  2031. *   -
  2032. *
  2033. ******************************************************************************/
  2034.  
  2035. static void Scale_Bicubic_Patch(Object, Vector, Trans)
  2036. OBJECT *Object;
  2037. VECTOR Vector;
  2038. TRANSFORM *Trans;
  2039. {
  2040.   int i, j;
  2041.   BICUBIC_PATCH *Patch = (BICUBIC_PATCH *) Object;
  2042.  
  2043.   for (i = 0; i < 4; i++)
  2044.   {
  2045.     for (j = 0; j < 4; j++)
  2046.     {
  2047.       VEvaluate(Patch->Control_Points[i][j], Patch->Control_Points[i][j], Vector);
  2048.     }
  2049.   }
  2050.  
  2051.   Precompute_Patch_Values(Patch);
  2052.  
  2053.   Compute_Bicubic_Patch_BBox(Patch);
  2054. }
  2055.  
  2056.  
  2057.  
  2058.  
  2059. /*****************************************************************************
  2060. *
  2061. * FUNCTION
  2062. *
  2063. *   Transform_Bicubic_Patch
  2064. *
  2065. * INPUT
  2066. *   
  2067. * OUTPUT
  2068. *   
  2069. * RETURNS
  2070. *   
  2071. * AUTHOR
  2072. *
  2073. *   Alexander Enzmann
  2074. *   
  2075. * DESCRIPTION
  2076. *
  2077. *   -
  2078. *
  2079. * CHANGES
  2080. *
  2081. *   -
  2082. *
  2083. ******************************************************************************/
  2084.  
  2085. static void Transform_Bicubic_Patch(Object, Trans)
  2086. OBJECT *Object;
  2087. TRANSFORM *Trans;
  2088. {
  2089.   int i, j;
  2090.   BICUBIC_PATCH *Patch = (BICUBIC_PATCH *) Object;
  2091.   
  2092.   for (i = 0; i < 4; i++)
  2093.   {
  2094.     for (j = 0; j < 4; j++)
  2095.     {
  2096.       MTransPoint(Patch->Control_Points[i][j], Patch->Control_Points[i][j], Trans);
  2097.     }
  2098.   }
  2099.   
  2100.   Precompute_Patch_Values(Patch);
  2101.   
  2102.   Compute_Bicubic_Patch_BBox(Patch);
  2103. }
  2104.  
  2105.  
  2106.  
  2107. /*****************************************************************************
  2108. *
  2109. * FUNCTION
  2110. *
  2111. *   Invert_Bicubic_Patch
  2112. *
  2113. * INPUT
  2114. *   
  2115. * OUTPUT
  2116. *   
  2117. * RETURNS
  2118. *   
  2119. * AUTHOR
  2120. *
  2121. *   Alexander Enzmann
  2122. *   
  2123. * DESCRIPTION
  2124. *
  2125. *   Inversion of a patch really doesn't make sense.
  2126. *
  2127. * CHANGES
  2128. *
  2129. *   -
  2130. *
  2131. ******************************************************************************/
  2132.  
  2133. static void Invert_Bicubic_Patch(Object)
  2134. OBJECT *Object;
  2135. {
  2136. }
  2137.  
  2138.  
  2139.  
  2140. /*****************************************************************************
  2141. *
  2142. * FUNCTION
  2143. *
  2144. *   Create_Bicubic_Patch
  2145. *
  2146. * INPUT
  2147. *   
  2148. * OUTPUT
  2149. *   
  2150. * RETURNS
  2151. *   
  2152. * AUTHOR
  2153. *
  2154. *   Alexander Enzmann
  2155. *   
  2156. * DESCRIPTION
  2157. *
  2158. *   -
  2159. *
  2160. * CHANGES
  2161. *
  2162. *   -
  2163. *
  2164. ******************************************************************************/
  2165.  
  2166. BICUBIC_PATCH *Create_Bicubic_Patch()
  2167. {
  2168.   BICUBIC_PATCH *New;
  2169.   
  2170.   New = (BICUBIC_PATCH *)POV_MALLOC(sizeof (BICUBIC_PATCH), "bicubic patch");
  2171.   
  2172.   INIT_OBJECT_FIELDS(New, BICUBIC_PATCH_OBJECT, &Bicubic_Patch_Methods)
  2173.     
  2174.     New->Patch_Type = - 1;
  2175.   
  2176.   New->U_Steps = 0;
  2177.   New->V_Steps = 0;
  2178.   
  2179.   New->Flatness_Value = 0.0;
  2180.   
  2181.   New->Node_Tree = NULL;
  2182.   
  2183.   /*
  2184.    * NOTE: Control_Points[4][4] is initialized in Parse_Bicubic_Patch.
  2185.    * Bounding_Sphere_Center,Bounding_Sphere_Radius, Normal_Vector[], and
  2186.    * IPoint[] are initialized in Precompute_Patch_Values.
  2187.    */
  2188.   
  2189.   return (New);
  2190. }
  2191.  
  2192.  
  2193.  
  2194. /*****************************************************************************
  2195. *
  2196. * FUNCTION
  2197. *
  2198. *   Copy_Bicubic_Patch
  2199. *
  2200. * INPUT
  2201. *   
  2202. * OUTPUT
  2203. *   
  2204. * RETURNS
  2205. *   
  2206. * AUTHOR
  2207. *
  2208. *   Alexander Enzmann
  2209. *   
  2210. * DESCRIPTION
  2211. *
  2212. *   -
  2213. *
  2214. * CHANGES
  2215. *
  2216. *   -
  2217. *
  2218. ******************************************************************************/
  2219.  
  2220. static void *Copy_Bicubic_Patch(Object)
  2221. OBJECT *Object;
  2222. {
  2223.   int i, j;
  2224.   BICUBIC_PATCH *New;
  2225.   
  2226.   New = Create_Bicubic_Patch();
  2227.   
  2228.   /* Do not do *New = *Old so that Precompute works right */
  2229.   
  2230.   New->Patch_Type = ((BICUBIC_PATCH *)Object)->Patch_Type;
  2231.  
  2232.   New->U_Steps = ((BICUBIC_PATCH *)Object)->U_Steps;
  2233.   New->V_Steps = ((BICUBIC_PATCH *)Object)->V_Steps;
  2234.   
  2235.   for (i = 0; i < 4; i++)
  2236.   {
  2237.     for (j = 0; j < 4; j++)
  2238.     {
  2239.       Assign_Vector(New->Control_Points[i][j], ((BICUBIC_PATCH *)Object)->Control_Points[i][j]);
  2240.     }
  2241.   }
  2242.   
  2243.   New->Flatness_Value = ((BICUBIC_PATCH *)Object)->Flatness_Value;
  2244.   
  2245.   Precompute_Patch_Values(New);
  2246.   
  2247.   return (New);
  2248. }
  2249.  
  2250.  
  2251.  
  2252. /*****************************************************************************
  2253. *
  2254. * FUNCTION
  2255. *
  2256. *   Destroy_Bicubic_Patch
  2257. *
  2258. * INPUT
  2259. *   
  2260. * OUTPUT
  2261. *   
  2262. * RETURNS
  2263. *   
  2264. * AUTHOR
  2265. *
  2266. *   Alexander Enzmann
  2267. *   
  2268. * DESCRIPTION
  2269. *
  2270. *   -
  2271. *
  2272. * CHANGES
  2273. *
  2274. *   -
  2275. *
  2276. ******************************************************************************/
  2277.  
  2278. static void Destroy_Bicubic_Patch(Object)
  2279. OBJECT *Object;
  2280. {
  2281.   BICUBIC_PATCH *Patch;
  2282.   
  2283.   Patch = (BICUBIC_PATCH *)Object;
  2284.   
  2285.   if (Patch->Patch_Type != 0)
  2286.   {
  2287.     if (Patch->Node_Tree != NULL)
  2288.     {
  2289.       bezier_tree_deleter(Patch->Node_Tree);
  2290.     }
  2291.   }
  2292.   
  2293.   POV_FREE(Patch);
  2294. }
  2295.  
  2296.  
  2297.  
  2298. /*****************************************************************************
  2299. *
  2300. * FUNCTION
  2301. *
  2302. *   Compute_Bicubic_Patch_BBox
  2303. *
  2304. * INPUT
  2305. *
  2306. *   Bicubic_Patch - Bicubic patch
  2307. *   
  2308. * OUTPUT
  2309. *
  2310. *   Bicubic_Patch
  2311. *   
  2312. * RETURNS
  2313. *   
  2314. * AUTHOR
  2315. *
  2316. *   Dieter Bayer
  2317. *   
  2318. * DESCRIPTION
  2319. *
  2320. *   Calculate the bounding box of a bicubic patch.
  2321. *
  2322. * CHANGES
  2323. *
  2324. *   Aug 1994 : Creation.
  2325. *
  2326. ******************************************************************************/
  2327.  
  2328. void Compute_Bicubic_Patch_BBox(Bicubic_Patch)
  2329. BICUBIC_PATCH *Bicubic_Patch;
  2330. {
  2331.   int i, j;
  2332.   VECTOR Min, Max;
  2333.  
  2334.   Make_Vector(Min, BOUND_HUGE, BOUND_HUGE, BOUND_HUGE);
  2335.   Make_Vector(Max, -BOUND_HUGE, -BOUND_HUGE, -BOUND_HUGE);
  2336.  
  2337.   for (i = 0; i < 4; i++)
  2338.   {
  2339.     for (j = 0; j < 4; j++)
  2340.     {
  2341.       Min[X] = min(Min[X], Bicubic_Patch->Control_Points[i][j][X]);
  2342.       Min[Y] = min(Min[Y], Bicubic_Patch->Control_Points[i][j][Y]);
  2343.       Min[Z] = min(Min[Z], Bicubic_Patch->Control_Points[i][j][Z]);
  2344.       Max[X] = max(Max[X], Bicubic_Patch->Control_Points[i][j][X]);
  2345.       Max[Y] = max(Max[Y], Bicubic_Patch->Control_Points[i][j][Y]);
  2346.       Max[Z] = max(Max[Z], Bicubic_Patch->Control_Points[i][j][Z]);
  2347.     }
  2348.   }
  2349.   
  2350.   Make_BBox_from_min_max(Bicubic_Patch->BBox, Min, Max);
  2351. }
  2352.  
  2353.